package pool

import (
	"sync"
	"sync/atomic"
	"yunpan/logger"
	"yunpan/store/ceph"
	"yunpan/utils"

	"go.uber.org/zap"
)

// BaseTask 基础任务结构
type BaseTask struct {
	retryCount int32        // 当前重试次数
	maxRetries int32        // 最大重试次数
	mu         sync.RWMutex // 保护任务状态
	done       bool         // 任务完成标志
}

// GetRetryCount 获取当前重试次数
func (t *BaseTask) GetRetryCount() int {
	return int(atomic.LoadInt32(&t.retryCount))
}

// incrementRetry 增加重试次数
func (t *BaseTask) incrementRetry() {
	atomic.AddInt32(&t.retryCount, 1)
}

// isDone 检查任务是否完成
func (t *BaseTask) isDone() bool {
	t.mu.RLock()
	defer t.mu.RUnlock()
	return t.done
}

// setDone 标记任务为完成
func (t *BaseTask) setDone() {
	t.mu.Lock()
	defer t.mu.Unlock()
	t.done = true
}

// HashTask 文件哈希计算任务
type HashTask struct {
	BaseTask
	data       []byte      // 需要计算哈希的数据
	resultChan chan string // 结果通道
	errChan    chan error  // 错误通道
	once       sync.Once   // 确保通道只关闭一次
}

// NewHashTask 创建新的哈希计算任务
func NewHashTask(data []byte, maxRetries int) *HashTask {
	return &HashTask{
		BaseTask:   BaseTask{maxRetries: int32(maxRetries)},
		data:       data,
		resultChan: make(chan string, 1),
		errChan:    make(chan error, 1),
	}
}

// Execute 执行哈希计算任务
func (t *HashTask) Execute() error {
	if t.isDone() {
		return nil
	}

	hash := utils.Sha1(t.data)
	t.resultChan <- hash

	t.setDone()
	t.once.Do(func() {
		close(t.resultChan)
		close(t.errChan)
	})
	return nil
}

// OnFailure 处理任务失败
func (t *HashTask) OnFailure(err error) {
	if t.isDone() {
		return
	}

	if t.GetRetryCount() < int(t.maxRetries) {
		t.incrementRetry()
		t.errChan <- err
	} else {
		t.setDone()
		t.once.Do(func() {
			close(t.resultChan)
			close(t.errChan)
		})
	}
}

// GetResult 获取哈希计算结果
func (t *HashTask) GetResult() (string, error) {
	select {
	case hash := <-t.resultChan:
		return hash, nil
	case err := <-t.errChan:
		return "", err
	}
}

// DBTask 数据库任务
type DBTask struct {
	BaseTask
	operation   func() error // 数据库操作函数
	done        chan error
	description string // 任务描述，用于日志
}

func NewDBTask(description string, maxRetries int, operation func() error) *DBTask {
	return &DBTask{
		BaseTask:    BaseTask{maxRetries: int32(maxRetries)},
		operation:   operation,
		done:        make(chan error, 1),
		description: description,
	}
}

// Execute 实现 Task 接口
func (t *DBTask) Execute() error {
	if t.isDone() {
		return nil
	}

	// 执行操作并记录日志
	if err := t.operation(); err != nil {
		logger.Error("数据库操作失败",
			zap.String("task", t.description),
			zap.Error(err),
		)
		t.done <- err
		return err
	}

	t.setDone()
	t.done <- nil
	return nil
}

// OnFailure 实现 Task 接口
func (t *DBTask) OnFailure(err error) {
	if t.isDone() {
		return
	}

	if t.GetRetryCount() < int(t.maxRetries) {
		t.incrementRetry()
	} else {
		t.setDone()
		t.done <- err
	}
}

// Wait 实现 WaitableTask 接口
func (t *DBTask) Wait() error {
	return <-t.done
}

// CephTask Ceph任务
type CephTask struct {
	BaseTask
	username    string
	operation   func(*ceph.StorageSession) error // Ceph 操作函数
	done        chan error
	description string // 任务描述，用于日志
}

func NewCephTask(username string, description string, maxRetries int,
	operation func(*ceph.StorageSession) error) *CephTask {
	return &CephTask{
		BaseTask:    BaseTask{maxRetries: int32(maxRetries)},
		username:    username,
		operation:   operation,
		done:        make(chan error, 1),
		description: description,
	}
}

// Execute 实现 Task 接口
func (t *CephTask) Execute() error {
	if t.isDone() {
		return nil
	}

	cephConn, err := ceph.GetCephConn(t.username)
	if err != nil {
		logger.Error("获取Ceph连接失败",
			zap.String("username", t.username),
			zap.String("task", t.description),
			zap.Error(err),
		)
		t.done <- err
		return err
	}

	// 执行操作并记录日志
	if err := t.operation(cephConn); err != nil {
		logger.Error("Ceph操作失败",
			zap.String("username", t.username),
			zap.String("task", t.description),
			zap.Error(err),
		)
		t.done <- err
		return err
	}

	t.setDone()
	t.done <- nil
	return nil
}

// OnFailure 实现 Task 接口
func (t *CephTask) OnFailure(err error) {
	if t.isDone() {
		return
	}

	if t.GetRetryCount() < int(t.maxRetries) {
		t.incrementRetry()
	} else {
		t.setDone()
		t.done <- err
	}
}

// Wait 实现 WaitableTask 接口
func (t *CephTask) Wait() error {
	return <-t.done
}

// WaitableTask 可等待的任务接口
type WaitableTask interface {
	Task
	Wait() error // 等待任务完成并返回结果
}

var (
	_ WaitableTask = (*CephTask)(nil)
	_ WaitableTask = (*DBTask)(nil)
	_ WaitableTask = (*HashTask)(nil)
)

// Wait 实现 WaitableTask 接口
func (t *HashTask) Wait() error {
    _, err := t.GetResult()
    return err
}